<?php
namespace app\api\model;
use app\admin\model\Freight;
use app\common\controller\UtilCommon;
use app\lib\exception\FailedException;
use app\lib\exception\NotFoundException;
use traits\model\SoftDelete;

class ProductCart extends Base
{
    use SoftDelete;
    public function productPrice(){
        return $this->hasMany("ProductPrice","product_id","product_id");
    }
    //老的加入购物车
    public function changeCartNumber($change_type,$product_id,$skuList,$uid,$user_id){
        $priceList = (new ProductPrice())->selectList([['product_id','eq',$product_id]],"*","type");
        if(!$priceList){
            return ['code'=>0,'msg'=>'所选商品暂未设置批发价格'];
        }
        $priceList = $priceList->toArray();
        $where_user_cart = [
            ['user_id','eq',$user_id],
            ['product_id','eq',$product_id]
        ];

        $total_number = 0;
        $type = 1;
        $userCart = (new \app\api\model\ProductCart())->selectList($where_user_cart,"id,sku,number");
        $userCart = $userCart->toArray();
        $number1=array_column($skuList,"number");
        $number2=array_column($userCart,"number");
        if($change_type==1){
            $total_number += array_sum($number1)+array_sum($number2);//总数量相加
        }else{
            $total_number += array_sum($number2)-array_sum($number1);//总数量相减
        }
        $sku_list = changeArrayKey($skuList,"sku");
        $insertCart = [];//新增的购物车
        $editCart = [];//修改的购物车
        foreach ($priceList as $key=>$value){
            if($total_number>=$value['min_number']){
                $type = $value['type'];
            }
        }
        foreach ($userCart as $key=>$value){
            if(isset($sku_list[$value['sku']])){
                if($change_type==1){
                    $value['number'] +=$sku_list[$value['sku']]['number'];
                }
                if($change_type==2){
                    $value['number'] -=$sku_list[$value['sku']]['number'];
                }
                if($value['number']<=0){
                    return ['code'=>0,'msg'=>'购物车的数量不能为0'];
                }
                $value['update_time'] = time();
                $value['type'] = $type;
                $value['uid'] = $uid;
                unset($sku_list[$value['sku']]);
            }else{
                $value['type'] = $type;
            }
            $editCart[] = $value;
        }
        foreach ($sku_list as $key=>$value){
            if($value['number']<=0){
                return ['code'=>0,'msg'=>'购物车的数量不能为0'];
            }
            if($change_type==2){
                return ['code'=>0,'msg'=>'不存在需要减少的库存'];
            }
            $insertCart[] =[
                'uid'     =>$uid,
                'type'     =>$type,
                'product_id'=>$product_id,
                'sku' =>$value['sku'],
                'number'=>$value['number'],
                'user_id'=>$user_id,
                'create_time'=>time(),
                'update_time'=>time()
            ];
        }
        if(count($insertCart)>0){
            $res = (new \app\api\model\ProductCart())->saveAll($insertCart);
            if(!$res){
                return ['code'=>0,'msg'=>'购物车新增失败'];
            }
        }
        if(count($editCart)>0){
            $res = (new \app\api\model\ProductCart())->saveAll($editCart);
            if(!$res){
                return ['code'=>0,'msg'=>'购物车修改失败'];
            }
        }
        return ['code'=>1];
    }
    //新的加入购物车
    public function changeCartNumberNew($change_type,$product_id,$skuList,$uid,$user_id){
        $priceList = (new ProductPrice())->selectList([['product_id','eq',$product_id]],"*","type");
        if(!$priceList){
            return ['code'=>0,'msg'=>'所选商品暂未设置批发价格'];
        }
        $priceList = $priceList->toArray();
        $where_user_cart = [['user_id','eq',$user_id]];
        $userCart = (new \app\api\model\ProductCart())->selectList($where_user_cart,"id,product_id,sku,number");
        $userCart = $userCart->toArray();

        $sku_list = changeArrayKey($skuList,"product_id");
        $insertCart = [];//新增的购物车
        $editCart = [];//修改的购物车
        foreach ($userCart as &$value){
            if(isset($sku_list[$value['product_id']])){
                if($change_type==1){
                    $value['number'] +=$sku_list[$value['product_id']]['number'];
                }
                if($change_type==2){
                    $value['number'] -=$sku_list[$value['product_id']]['number'];
                }
                if($value['number']<=0){
                    return ['code'=>0,'msg'=>'购物车的数量不能为0'];
                }
                foreach ($priceList as $ke=>$val){
                    if($value['number']>=$val['min_number']){
                        $value['type']= $val['type'];
                    }
                }
                $value['update_time'] = time();
                $value['uid'] = $uid;
                unset($sku_list[$value['product_id']]);
            }
            $editCart[] = $value;
        }
        foreach ($sku_list as &$value){
            $value['type'] = 1;
            if($value['number']<=0){
                return ['code'=>0,'msg'=>'购物车的数量不能为0'];
            }
            if($change_type==2){
                return ['code'=>0,'msg'=>'不存在需要减少的库存'];
            }
            if(!isset($value["hall_id"])){
                return ['code'=>0,'msg'=>'未选择货位号'];
            }
            foreach ($priceList as $ke=>$val){
                if($value['number']>=$val['min_number']){
                    $value['type']= $val['type'];
                }
            }
            $insertCart[] =[
                'uid'     =>$uid,
                'type'     => $value['type'],
                'product_id'=>$product_id,
//                'sku' =>$value['sku'],
                'number'=>$value['number'],
                'hall_id'=>$value['hall_id'],
                'user_id'=>$user_id,
                'create_time'=>time(),
                'update_time'=>time()
            ];
        }

        if(count($insertCart)>0){
            $res = (new \app\api\model\ProductCart())->saveAll($insertCart);
            if(!$res){
                return ['code'=>0,'msg'=>'购物车新增失败'];
            }
        }
        if(count($editCart)>0){
            $res = (new \app\api\model\ProductCart())->saveAll($editCart);
            if(!$res){
                return ['code'=>0,'msg'=>'购物车修改失败'];
            }
        }
        return ['code'=>1];
    }
    //修改购物车数量
    public function changeNumberNew($change_type,$product_id,$skuList,$uid,$user_id){
        $priceList = (new ProductPrice())->selectList([['product_id','eq',$product_id]],"*","type");
        if(!$priceList){
            return ['code'=>0,'msg'=>'所选商品暂未设置批发价格'];
        }
        $priceList = $priceList->toArray();
        $where_user_cart = [
            ['user_id','eq',$user_id],
            ['product_id','eq',$product_id]
        ];
        $userCart = (new \app\api\model\ProductCart())->selectList($where_user_cart,"id,product_id,sku,number");
        $userCart = $userCart->toArray();

        $sku_list = changeArrayKey($skuList,"product_id");
        $insertCart = [];//新增的购物车
        $editCart = [];//修改的购物车
        foreach ($userCart as &$value){
            if(isset($sku_list[$value['product_id']])){
                if($change_type==1){
                    $value['number'] =$sku_list[$value['product_id']]['number'];
                }
                if($change_type==2){
                    $value['number'] =$sku_list[$value['product_id']]['number'];
                }
                if($value['number']<=0){
                    return ['code'=>0,'msg'=>'购物车的数量不能为0'];
                }
                foreach ($priceList as $ke=>$val){
                    if($value['number']>=$val['min_number']){
                        $value['type']= $val['type'];
                    }
                }
                $value['update_time'] = time();
                $value['uid'] = $uid;
                unset($sku_list[$value['product_id']]);
            }
            $editCart[] = $value;
        }
        foreach ($sku_list as &$value){
            $value['type'] = 1;
            if($value['number']<=0){
                return ['code'=>0,'msg'=>'购物车的数量不能为0'];
            }
            if($change_type==2){
                return ['code'=>0,'msg'=>'不存在需要减少的库存'];
            }
            foreach ($priceList as $ke=>$val){
                if($value['number']>=$val['min_number']){
                    $value['type']= $val['type'];
                }
            }
            $insertCart[] =[
                'uid'     =>$uid,
                'type'     => $value['type'],
                'product_id'=>$product_id,
//                'sku' =>$value['sku'],
                'number'=>$value['number'],
                'user_id'=>$user_id,
                'create_time'=>time(),
                'update_time'=>time()
            ];
        }

        if(count($insertCart)>0){
            $res = (new \app\api\model\ProductCart())->saveAll($insertCart);
            if(!$res){
                return ['code'=>0,'msg'=>'购物车新增失败'];
            }
        }
        if(count($editCart)>0){
            $res = (new \app\api\model\ProductCart())->saveAll($editCart);
            if(!$res){
                return ['code'=>0,'msg'=>'购物车修改失败'];
            }
        }
        return ['code'=>1];
    }
    //通过购物车 获取 商品和库存
    public function getStock($type,$idList){
        $cartList = [];
        $where = [
            ['a.id','in',$idList],
        ];
        $field = "a.id,a.sku_remark as sku,SUM(b.stock) stock";
        switch ($type){
            //1表示线上商家
            case 1:
                $cartList = (new Product())
                    ->alias("a")
                    ->join("om_warehouse c","a.uid = c.uid","left")
                    ->join("om_warehouse_general_sku b","a.id = b.product_id and c.id = b.warehouse_id","left")
                    ->field($field)
                    ->group("a.id")
                    ->where($where)
                    ->whereNull("b.delete_time")
                    ->select();
                break;
           //品牌店商家
            case 2:
                $cartList = (new Product())
                    ->alias("a")
                    ->join("om_warehouse c","a.uid = c.uid","left")
                    ->join("om_warehouse_general_sku b","a.id = b.product_id and c.id = b.warehouse_id","left")
                    ->field($field)
                    ->group("a.id")
                    ->where($where)
                    ->whereNull("b.delete_time")
                    ->select();
                break;
           //贸易商
            case 3:
                $where[] =['b.warehouse_id','in',2];
                $cartList =  (new Product())
                    ->alias("a")
                    ->join("om_warehouse_general_sku b","a.id = b.product_id","left")
                    ->field($field)
                    ->group("a.id")
                    ->where($where)
                    ->whereNull("b.delete_time")
                    ->select();
                break;
        }
        $cartList = $cartList->toArray();
        $cartList = changeArrayKey($cartList,"id");
        return $cartList;
    }

    /**
     * 检查购物车
     * @param $cartList
     * @param int $user_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function checkCart($cartList,$user_id = 0){
        $typeList = array_column($cartList,"type");
        $productList = array_column($cartList,"product_id");
        $typeList = array_unique($typeList);
        if(count($typeList)==0){
            return['code'=>0,'msg'=>'请选择购物车'];
        }
        if(count($typeList)>1){
            return['code'=>0,'msg'=>'不可以同时在不同的商家类型下结算'];
        }

        $product = [];//将购物车 按产品分组 并吧价格规则放到里面
        foreach ($cartList as $key=>$value){
            //检查货位号
            if($value["type"] == 3 && !isset($value['hall_id'])){
                return['code'=>0,'msg'=>$value['product_name']."未选择货位号"];
            }
            //组合商品
            if(!isset($product[$value['product_id']])){
                $product[$value['product_id']]= [
                    'total_number'=>0,
                    'product_name'        =>$value['product_name'],
                    'hall_id'             =>$value['hall_id'],//必须选择货位号
                ];
            }
            $product[$value['product_id']]['total_number']+=$value['number'];
        }

        //获取会员组别
        $user_type = 1; //默认组别为免费会员$user_type = 1; //默认免费会员
        if(isset($user_id) && $user_id != 0){
            //获取会员组别
            $user_type = (new User())->getUserType($user_id);
        }

        //--------------------------------------------------------
        // 计算价位 - 规则
        // 1.当不满足微批 中批数量时，一律按照零售价
        // 2.当是会员/企业商,并且满足微批中批数量，按照相应价格  user_type 2,3
        // 3.当是会员/企业商，但超出中批价格时，按照中批价格计算
        // 免费 1   会员 2  企业商 3
        //--------------------------------------------------------
        $productRule  = (new Product())->getProductRule($cartList);
        foreach ($product as $key=>$value){
            //获取微批价与中批价格
            $min_num = [];
            $max_num = [];
            foreach ($productRule[$key]['product_price'] as $ke=>$val){
                if($val["type"] == 1){
                    $min_num = $val;
                }
                if($val["type"] == 2){
                    $max_num = $val;
                }
            }

            if($user_type == 1){
                //使用零售价
                $product[$key]['price'] = $productRule[$key]['product_price_one'];
            }
            else {
                if(!isset($productRule[$key])){
//                    return['code'=>0,'msg'=>$value['product_name']."的起批数量不足"];
                    //起批数量未设定(不存在)，则直接使用零售价
                    $product[$key]['price'] = $productRule[$key]['product_price_one'];
                }

                $OK = 0;
                //匹配批发价数量区间
                foreach ($productRule[$key]['product_price'] as $ke=>$val){
                    if($value['total_number']>=$val['min_number']&&$value['total_number']<=$val['max_number']){
                        $OK++;
                        $product[$key]['price'] = $val['price'];
                    }
                }

                //若批发区间内无匹配，判断是小于最小起批还是大于最大起批
                if($OK==0){
                    if($value['total_number'] < $min_num["min_number"]){
                        $product[$key]['price'] = $productRule[$key]['product_price_one'];
                    }
                    else if($value['total_number'] > $max_num['max_number']){
                        $product[$key]['price'] = $max_num['price'];
                    }
                    else{
                        //其他特殊情况则直接使用零售价
                        $product[$key]['price'] = $productRule[$key]['product_price_one'];
                    }
//                    return['code'=>0,'msg'=>$value['product_name']."的起批数量不在范围内"];
                }
            }

            //如果价格为0  则默认使用微批价格
            if($product[$key]['price']=="0.00"){
                $product[$key]['price'] = $min_num['price'];
            }
        }
        //检查库存
        $skuStock     =  $this->getStock($typeList[0],$productList);
        foreach ($cartList as $key=>$value){
            if(!isset($skuStock[$value['product_id']]['stock'])||$skuStock[$value['product_id']]['stock'] < $value['number']){
                return['code'=>0,'msg'=>$value['product_name']."的库存不足"];
            }
            $cartList[$key]['price'] = $product[$value['product_id']]['price'];
        }

        return ['code'=>1,'cartList'=>$cartList];
    }
    //获取购物车的数据
    public function getCart($post){
        $where = [
            ['a.user_id','eq',$post['user_id']],
            ['a.id','in',$post['id']],
            ['b.is_publish','in',2],
            ['c.status','eq',2],
            ['c.use_status','eq',1],
        ];

        $field = "a.id,a.product_id,a.sku,a.number,a.update_time,a.uid,b.fcl_weight,b.fcl_volume,b.unit_number,b.one_weight,b.product_name,b.cover_img,b.unit,c.name,c.type,b.sku_remark,a.hall_id";
        $cartList =$this
            ->alias("a")
            ->join("om_product b","a.product_id = b.id","right")
            ->join("om_shop c","a.uid = c.id","right")
//            ->join("om_product_sku d","a.product_id = d.product_id and a.sku = d.sku","right")
            ->field($field)
            ->where($where)
            ->select();
        $cartList = $cartList->toArray();
        return $cartList;
    }
    //根据时间戳将订单排序
    public function getShopProduct($list){
        $cartList = [];
        //获取交易大厅自提地址
        $config_model = (new \app\admin\controller\config\Config())->getToTheAddress(1);

        foreach ($list as $key=>$value){
            $value['cover_img'] = imgUrlToAbsolute($value['cover_img']);
            //判断是否有单价，若无单价则使用微批价
            $value["price"] = (isset($value["product_price_one"]) && $value["product_price_one"] != 0) ? $value["product_price_one"] : $value["price"];
            if($value["type"] == 3){
                if(!isset($cartList[0])) {
                    //第一次初始化万享集商品及自提地址
                    $cartList[0] = [
                        'productList' => [],
                        'type' => 3,
                        'sort' => 0,
                        'shop_name' => "万享集",
                        'pick_address' => "万享集仅限包邮",//自提地址
                        'uid' => '0',
                        'name' => "万享集",
                        'update_time' => time()
                    ];
                    $cartList[0]['pick_address'] = $config_model['address'];
                }
                array_push($cartList[0]['productList'],$value);
                continue;
            }
            if(!isset($cartList[$value['uid']])){
                $cartList[$value['uid']] = [
                    'shop_name'=>$value['name'],
                    'pick_address'=>(new Shop())->findOne([['id','eq',$value['uid']]],"pick_address"),//自提地址
                    'uid' =>$value['uid'],
                    'name' =>$value['name'],
                    'type'=>$value['type'],
                    'update_time'=>$value['update_time'],
                    'sort' =>strtotime($value['update_time']),
                    'productList'=>[],
                ];
                //若商家无自提地址则赋值交易大厅自提地址
                if($cartList[$value['uid']]["pick_address"] == null){
                    $config_model = (new \app\admin\controller\config\Config())->getToTheAddress(1);
                    $cartList[$value['uid']]["pick_address"] = $config_model['address'];
                }
                unset($value['name']);
                unset($value['type']);
                unset($value['update_time']);
            }else{
                if($cartList[$value['uid']]['update_time'] < $value['update_time']) {
                    $cartList[$value['uid']]['update_time'] = $value['update_time'];
                    $cartList[$value['uid']]['sort'] = strtotime($value['update_time']);
                }
            }
            $cartList[$value['uid']]['productList'][] = $value;
        }
        $cartList = array_values($cartList);
        //对数组按照降序排列
        array_multisort(array_column($cartList,'sort'),SORT_DESC,$cartList);
        return $cartList;
    }

    /**
     * 计算运费及商品价格
     * @param $user_id
     * @param $address_id
     * @param $getType
     * @param $rule
     * @param $cartList
     * @return array
     * @throws NotFoundException
     */
    public function getFreightByAddress($user_id, $address_id, $getType, $rule, $cartList){
        $total_freight= 0; //运费
        $total_price = 0;  //商品总价格
        $all_number= 0;    //商品总数
        $total_product = 0;//产品价格
        $user_address= ""; //用户收货地址

        if($address_id!=0&&$getType==1){ //地址不为0 并且 取货方式为物流的情况下
             $user_address = (new UserAddress())->findOne([['user_id','eq',$user_id],['id','eq',$address_id]]);
             if(!$user_address){
                 throw new NotFoundException(['msg'=>'用户地址不存在']);
             }
        }
        if($getType==1){
            //旧:不需要考虑地址，现在订单运费根据商品总价而定
            //2019-12-16 需要进行判断  根据地址距离获取物流金额模板
            foreach ($cartList as &$value){
                $product = [];
                $value['freight'] = 0;
                $value['total_price'] = 0;
                $value['total_number'] = 0 ;
                $value['total_unit'] = 0;
                $value['freight_type'] = $rule['freight_type'];
                foreach ($value['productList'] as $val){
                    $total_price+= $val['number']*$val['price'];
                    $value['total_price'] +=$val['number']*$val['price'];
                    $value['total_number'] += $val['number'];
                    $all_number+=$val['number'];
                    if(!isset($product[$val['product_id']])){
                        $product[$val['product_id']]= $val;
                    }
                    else{
                        $product[$val['product_id']]['number']+=$val['number'];
                    }
                }
                $total_product+=count($product);

                $value['total_price'] = number_format($value['total_price'],2,".","");
            }

            //-----------
            // 计算运费
            //-----------
            if($user_address != ""){
                //查询地址信息
                $areaWhere["id"] = $user_address["area_id"];
                $areaService = new Area();
                $center = $areaService->findOne($areaWhere,"center");

                $config = (new \app\admin\model\Config())->getConfigKey();
                $freight_center = $config['freight_center'];

                //计算直线距离
                $km = (new UtilCommon())->getDistance($freight_center,$center);

                //查询这个范围下的运费模板有没有
                $where_freight = [
                        ['min_km','elt',$km],
                        ['max_km','egt',$km],
                        ['min_unit','elt',$total_price],
                        ['max_unit','egt',$total_price],
                ];
                $total_freight = (new Freight())->findOne($where_freight,"price");
                if(!$total_freight){
                    //如果没有则取最贵运费
                    $total_freight = (new Freight())->field("price")->order("price desc")->find();
                    $total_freight = $total_freight["price"];
                }

                $total_price+=$total_freight;
            }
         }else{
             foreach ($cartList as &$value){
                 $value['freight'] = 0;
                 $value['total_price'] = 0;
                 $value['total_number'] = 0 ;
                 $value['total_unit']  = 0;
                 $value['freight_type'] = $rule['freight_type'];
                 //获取供应商自提地址
                 foreach ($value['productList'] as &$val){
                     $value['total_price'] +=$val['number']*$val['price'];
                     $value['total_number'] += $val['number'];
                     $all_number += $val['number'];
                     $total_price+= $val['number']*$val['price'];
                 }
                 $value['total_price'] = number_format($value['total_price'],2,".","");
             }
         }
         //不排序处理订单了
        return ['cartList'=>$cartList,'total_freight'=>$total_freight,'total_price'=>number_format($total_price,2,".",""),'all_number'=>$all_number,'total_product'=>$total_product,'user_address'=>$user_address];
    }

    public function productSort($cartList){
        foreach ($cartList as &$value){
            $product= [];
            foreach ($value['productList'] as &$val){
                if(!isset($product[$val['product_id']])){
                    $product[$val['product_id']]= [
                        'cover_img' =>$val['cover_img'],
                        'product_name'=>$val['product_name'],
                        'skuList'     =>[]
                    ];
                }
                $product[$val['product_id']]['skuList'][]=$val;
            }
            $product = array_values($product);
            $value['productList'] = $product;
        }
        return $cartList;
    }

    /**
     * 根据订单价格计算运费
     */
    public function getFreightMoney($total_price,$address_id){
        //
    }
}
